package com.info33.platform.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.info33.platform.business.app.entity.AppBanner;
import com.info33.platform.business.app.service.AppBannerService;
import com.info33.platform.business.app.util.enmus.AppBannerEnum;
import com.info33.platform.common.constant.TableConstant;
import com.info33.platform.common.mvc.vo.Result;
import com.info33.platform.system.dao.SysAppMenuDao;
import com.info33.platform.system.dao.SysAppMenuFastDao;
import com.info33.platform.system.dao.SysAppMenuRoleDao;
import com.info33.platform.system.dao.SysAppTenantMenuDao;
import com.info33.platform.system.dto.SysAppTenantMenuDTO;
import com.info33.platform.system.entity.SysAppMenu;
import com.info33.platform.system.entity.SysAppMenuFast;
import com.info33.platform.system.entity.SysAppMenuRole;
import com.info33.platform.system.entity.SysAppTenantMenu;
import com.info33.platform.system.service.SysAppTenantMenuService;
import com.info33.platform.system.vo.SysAppHomeVO;
import com.info33.platform.system.vo.SysAppTenantMenuVO;
import com.info33.platform.system.vo.SysUserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author admin
 */
@Service
public class SysAppTenantMenuServiceImpl extends ServiceImpl<SysAppTenantMenuDao, SysAppTenantMenu> implements SysAppTenantMenuService {

    @Autowired
    private SysAppTenantMenuDao sysAppTenantMenuDao;
    @Autowired
    private SysAppMenuDao sysAppMenuDao;
    @Autowired
    private SysAppMenuRoleDao sysAppMenuRoleDao;
    @Autowired
    private SysAppMenuFastDao sysAppMenuFastDao;
    @Autowired
    private AppBannerService appBannerService;

    @Override
    public SysAppHomeVO appHome(SysUserVO currentUser) {
        SysAppHomeVO vo = new SysAppHomeVO();
        vo.setContent(new ArrayList<>());
        // 轮播图
        CompletableFuture<List<AppBanner>> banner = CompletableFuture.supplyAsync(() -> appBannerService.pcBanner(AppBannerEnum.MAPP_HOME, currentUser.getTenant().getId()))
                .whenComplete((appBanners, throwable) -> vo.setBanners(appBanners));
        // 添加菜单
        CompletableFuture<List<SysAppTenantMenuVO>> menu = CompletableFuture.supplyAsync(() -> sysAppTenantMenuDao.appHome(currentUser))
                .whenComplete((list, throwable) -> {
                    if (!ObjectUtils.isEmpty(list)) {
                        if (list.size() == 11) {
                            list.remove(list.size() - 2);
                        } else {
                            list.remove(list.size() - 1);
                        }
                    }
                    vo.setTenantMenuVOList(list);
                });
        CompletableFuture.allOf(banner, menu).join();
        return vo;
    }

    @Override
    public SysAppTenantMenuVO appMore(SysUserVO currentUser) {
        SysAppTenantMenuVO vo = new SysAppTenantMenuVO();
        // 快捷菜单
        CompletableFuture<List<SysAppMenuFast>> fast = CompletableFuture.supplyAsync(() -> sysAppMenuFastDao.selectList(new QueryWrapper<SysAppMenuFast>()
                        .select("menu_id", "type")
                        .eq(TableConstant.CREATE_BY, currentUser.getSysTenantUserVO().getId())))
                .whenComplete((appMenuFast, throwable) -> vo.setMenuFast(appMenuFast));
        // 菜单分组
        CompletableFuture<List<SysAppTenantMenuVO>> menu = CompletableFuture.supplyAsync(() -> sysAppTenantMenuDao.menuMore(currentUser))
                .whenComplete((allMenu, throwable) -> {
                    List<SysAppTenantMenuVO> list = allMenu.stream().filter(l -> l.getMenuVO().getPid().equals(1L)).collect(Collectors.toList());
                    list.forEach(l -> l.setTenantMenuVOS(allMenu.stream().filter(ll -> ll.getMenuVO().getPid().equals(l.getMenuId())).collect(Collectors.toList())));
                    vo.setTenantMenuVOS(list);
                });
        CompletableFuture.allOf(fast, menu).join();
        return vo;
    }

    @Override
    public List<SysAppMenu> appHomeMenuToSort(SysUserVO currentUser) {
        return sysAppMenuRoleDao.appHomeMenuToSort(currentUser);
    }

    @Override
    public IPage<SysAppTenantMenuVO> pcPage(Page<SysAppTenantMenu> page, SysAppTenantMenuDTO dto, SysUserVO currentUser) {
        return sysAppTenantMenuDao.pcPage(page, dto, currentUser);
    }

    @Override
    public SysAppTenantMenuVO pcDetail(Long id) {
        SysAppTenantMenuVO vo = sysAppTenantMenuDao.infoWithBase(id);
        vo.setRoleVOList(sysAppTenantMenuDao.roleListById(id));
        vo.setAll(!ObjectUtils.isEmpty(sysAppMenuRoleDao.selectOne(new QueryWrapper<SysAppMenuRole>()
                .select(TableConstant.ID)
                .eq("menu_id", id)
                .eq("type", 3)
                .last(TableConstant.LIMIT_ONE))));
        vo.setTenantUserVOList(sysAppTenantMenuDao.userListById(id));
        return vo;
    }

    @Override
    public Result<Object> pcReset(Long id) {
        return this.update(new UpdateWrapper<SysAppTenantMenu>()
                .setSql("name=null, img_url=null, sort=1")
                .eq(TableConstant.ID, id)) ? Result.ok() : Result.error();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result<Object> pcEdit(SysAppTenantMenuDTO dto) {
        SysAppTenantMenu entity = new SysAppTenantMenu();
        BeanUtils.copyProperties(dto, entity);
        SysAppMenu sysAppMenu = new SysAppMenu();
        sysAppMenu.setId(dto.getMenuDTO().getId());
        sysAppMenu.setUrl(dto.getMenuDTO().getUrl());
        sysAppMenuDao.updateById(sysAppMenu);
        return sysAppTenantMenuDao.updateById(entity) != 1
                ? Result.error(Result.RESULT_ERROR_PUBLIC_MSG)
                : Result.ok();
    }

    @Override
    public List<SysAppTenantMenuVO> pcTree(Long tenantId) {
        List<SysAppTenantMenuVO> list = sysAppTenantMenuDao.pcTree(tenantId);
        List<SysAppTenantMenuVO> collect = list.stream().filter(l -> l.getMenuVO().getPid().equals(1L)).collect(Collectors.toList());
        collect.forEach(l -> l.setTenantMenuVOS(list.stream().filter(ll -> ll.getMenuVO().getPid().equals(l.getMenuVO().getId())).collect(Collectors.toList())));
        return collect;
    }

    @Override
    public List<SysAppMenu> appHomeMenu(SysUserVO currentUser) {
        return sysAppMenuRoleDao.appHomeMenu(currentUser);
    }

}